package com.zhenzu.lock;

import java.util.concurrent.locks.ReentrantLock;

/**
 * synchronized和Lock的区别
 * Lock不是Java语言内置的，synchronized是Java语言关键词，是内置特性。Lock是一个类，通过这个类可以实现同步访问。
 * 采用synchronized不需要用户去手动释放锁，当synchronized方法或者synchronized代码块执行完成后，
 * 系统会自动让线程释放对锁的占用，而Lock则必须要用户去手动释放锁，如果不主动释放，则可能出现死锁情况。
 */
class LTicket {
    // 创建可重入锁
    private final ReentrantLock lock = new ReentrantLock();
    private int number = 30;

    /**
     * 卖票的方法
     */
    public void sale() {
        // 上锁
        lock.lock();

        try {
            if (number > 0) {
                System.out.println(Thread.currentThread().getName() + "：卖出" + number--
                        + "  剩余：" + number);
            }
        } finally {
            // 解锁
            lock.unlock();
        }
    }
}

public class LockSaleTicket {
    public static void main(String[] args) {
        LTicket lTicket = new LTicket();

        new Thread(() -> {
            for (int i = 0; i < 40; i++) {
                lTicket.sale();
            }
        }, "AA").start();

        new Thread(() -> {
            for (int i = 0; i < 40; i++) {
                lTicket.sale();
            }
        }, "BB").start();

        new Thread(() -> {
            for (int i = 0; i < 40; i++) {
                lTicket.sale();
            }
        }, "CC").start();

    }
}